#include <cstdlib>
#include <math.h>

#include "../include/QNode.h"
#include "../include/QInternalNode.h"
#include "../include/QLeafNode.h"

QInternalNode::QInternalNode(int numDim) {
    if (numDim > 0) {
        this->childs_count = (int) pow((double) 2, numDim);
        childs = new QNode*[this->childs_count];
        for (int i = 0; i < childs_count; i++) {
            this->childs[i] = new QLeafNode(this, i);
        }

        //Adjust left and right pointers for each bucket
        ((QLeafNode*) (this->childs[0]))->nextRightLeafNode = ((QLeafNode*) (this->childs[1])); //MODIFIED @ 10 MARCH 2011 BY BASMAH
        ((QLeafNode*) (this->childs[1]))->nextLeftLeafNode = ((QLeafNode*) (this->childs[0])); //Modified 
        uint32_t i;
        for (i = 1; i <this->childs_count - 1; i++) {
            if (this->childs[i] != NULL) {
                if (this->childs[i + 1] != NULL) {
                    ((QLeafNode*) (this->childs[i]))->nextRightLeafNode = ((QLeafNode*) (this->childs[i + 1])); //Modified
                    ((QLeafNode*) (this->childs[i + 1]))->nextLeftLeafNode = ((QLeafNode*) (this->childs[i])); //Modified by Basmah
                }

            } else
                ((QLeafNode*) (this->childs[i]))->nextRightLeafNode = NULL;
        }
        ((QLeafNode*) (this->childs[i]))->nextRightLeafNode = NULL; //MOdified						
        /*Region ends for  SetLeft and Right Pointers  */


        this->splitter.attribute_count = numDim; // Number of dimension is input
        this->splitter.value = new Attribute*[numDim];
        for (int i = 0; i < numDim; i++)
            this->splitter.value[i] = new Attribute;
    }
}

QInternalNode::~QInternalNode(void) {
    for (int i = 0; i < this->childs_count; i++) {
        if (this->childs[i] != NULL) {
            if (this->childs[i]->getType() == 1)
                ((QInternalNode*) (this->childs[i]))->~QInternalNode();
            else if (this->childs[i]->getType() == 2)
                ((QLeafNode*) (this->childs[i]))->destruct(true);

            delete this->childs[i];
        }
    }

    delete this->childs;
}

bool QInternalNode::insertChild(QNode *c, uint32_t bucketNum) {
    try {
        this->childs[bucketNum] = c;
        return true;
    } catch (...) {
        return false;
    }
    return true;
}

bool QInternalNode::hasChildAt(uint32_t bucketNum) {

    if (this->childs[bucketNum] != NULL)
        return true;
    return false;
}

